package com.shrct.businessprocess.customerservice.impl;

import com.google.common.base.Objects;
import com.shrct.businessprocess.customerservice.RCFaultLevel;
import com.shrct.businessprocess.customerservice.RCFaultReport;
import com.shrct.businessprocess.customerservice.RCFaultReportEvent;
import com.shrct.businessprocess.customerservice.RCFaultReportEventType;
import com.shrct.businessprocess.customerservice.RCFaultReportFlow;
import com.shrct.businessprocess.customerservice.RCFaultReportProduct;
import com.shrct.businessprocess.customerservice.RCFaultReportRMAInfo;
import com.shrct.businessprocess.customerservice.RCFaultStatus;
import com.shrct.businessprocess.customerservice.RCFaultWorkItem;
import com.shrct.businessprocess.customerservice.RCServiceRecord;
import com.shrct.businessprocess.customerservice.RCTimeLevel;
import com.shrct.businessprocess.customerservice.impl.RCFaultReportEventImpl;
import com.shrct.businessprocess.customerservice.impl.RCFaultReportProductImpl;
import com.shrct.businessprocess.customerservice.impl.RCFaultWorkItemImpl;
import com.shrct.businessprocess.customerservice.impl.RCServiceRecordImpl;
import com.shrct.businessprocess.customerservice.proxy.RCFaultReportProxy;
import com.shrct.businessprocess.organization.RCCTOProvider;
import com.shrct.businessprocess.organization.RCEmployee;
import com.shrct.businessprocess.organization.RCEnterprise;
import com.shrct.businessprocess.organization.impl.RCEmployeeImpl;
import com.shrct.businessprocess.organization.impl.RCEnterpriseImpl;
import com.shrct.businessprocess.product.RCIdentifiablePhysicalProductEntry;
import edu.fudan.langlab.domain.organization.Party;
import edu.fudan.langlab.domain.security.ISystemUserService;
import edu.fudan.langlab.domain.statemachine.ModelObjectLogService;
import edu.fudan.mylang.common.StringExtensions;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IGenericQuery;
import edu.fudan.mylang.pf.IObjectFactory;
import edu.fudan.mylang.utils.DateUtil;
import java.util.Collection;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.InputOutput;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

@Entity
@DiscriminatorValue("RCFAULTREPORT_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "rcfaultreport")
public class RCFaultReportImpl extends BaseModelObject implements RCFaultReport {
  public RCFaultReportImpl() {
    super();
  }
  
  private RCFaultReportFlow Flow;
  
  public RCFaultReportFlow getFlow() {
    return this.Flow;
  }
  
  private ModelObjectLogService getModelObjectLogService() {
    return getBeanFactory().getBean(ModelObjectLogService.class);
  }
  
  private void _start(final String comment) {
    
    this.timeLevel = RCTimeLevel.level0h;
    this.createEvent(comment, RCFaultReportEventType.report);
    this.status = RCFaultStatus.reported;
    Flow=RCFaultReportFlow.reported;
  }
  
  public void start(final String comment) {
    if(Flow==null){
    	_start(comment);
    	getModelObjectLogService().createLog(this,"Flow","Start");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCFaultReportEventsManager.class).fireStarted(this);					
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException("allready started");
    }
  }
  
  private void _processReport(final Date time, final String comment) {
    
    this.createEvent(comment, RCFaultReportEventType.processReport, time);
    this.status = RCFaultStatus.processed;
    Flow=RCFaultReportFlow.processed;
  }
  
  public void processReport(final Date time, final String comment) {
    if(Flow==RCFaultReportFlow.reported){
    	_processReport(time,comment);
    	getModelObjectLogService().createLog(this,"Flow","processReport");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCFaultReportEventsManager.class).fireProcessReport(this,time,comment);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Flow.name());
    }
  }
  
  private void __delete() {
    
    Flow=RCFaultReportFlow.finished;
  }
  
  public void _delete() {
    if(Flow==RCFaultReportFlow.reported){
    	__delete();
    	getModelObjectLogService().createLog(this,"Flow","_delete");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCFaultReportEventsManager.class).fire_delete(this);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Flow.name());
    }
  }
  
  private void _requireRMA(final String comment) {
    
    this.createEvent(comment, RCFaultReportEventType.requireRMA);
    this.status = RCFaultStatus.waiting4rma;
    Flow=RCFaultReportFlow.waiting4rma;
  }
  
  public void requireRMA(final String comment) {
    if(Flow==RCFaultReportFlow.processed){
    	_requireRMA(comment);
    	getModelObjectLogService().createLog(this,"Flow","requireRMA");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCFaultReportEventsManager.class).fireRequireRMA(this,comment);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Flow.name());
    }
  }
  
  private void _repairPerformed(final String comment) {
    
    this.createEvent(comment, RCFaultReportEventType.finish);
    this.status = RCFaultStatus.finished;
    Flow=RCFaultReportFlow.finished;
  }
  
  public void repairPerformed(final String comment) {
    if(Flow==RCFaultReportFlow.processed){
    	_repairPerformed(comment);
    	getModelObjectLogService().createLog(this,"Flow","repairPerformed");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCFaultReportEventsManager.class).fireRepairPerformed(this,comment);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Flow.name());
    }
  }
  
  private void _pend(final String comment) {
    
    this.createEvent(comment, RCFaultReportEventType.pend);
    this.status = RCFaultStatus.pending;
    Flow=RCFaultReportFlow.pending;
  }
  
  public void pend(final String comment) {
    if(Flow==RCFaultReportFlow.processed||Flow==RCFaultReportFlow.waiting4rma){
    	_pend(comment);
    	getModelObjectLogService().createLog(this,"Flow","pend");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCFaultReportEventsManager.class).firePend(this,comment);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Flow.name());
    }
  }
  
  private void _upgrade2Level(final RCTimeLevel level) {
    
    final RCFaultLevel faultLevel = this.faultLevel;
    boolean _matched = false;
    if (!_matched) {
      if (Objects.equal(faultLevel,RCFaultLevel.level1)) {
        _matched=true;
        boolean _matched_1 = false;
        if (!_matched_1) {
          if (Objects.equal(level,RCTimeLevel.level1h)) {
            _matched_1=true;
            final RCEmployee employee = this.seniorEngineer;
            this.notifyEmployee(employee, "\u8D44\u6DF1\u5DE5\u7A0B\u5E08");
          }
        }
        if (!_matched_1) {
          if (Objects.equal(level,RCTimeLevel.level4h)) {
            _matched_1=true;
            final RCEmployee employee_1 = this.techSupport;
            this.notifyEmployee(employee_1, "\u6280\u672F\u652F\u6301\u7ECF\u7406");
          }
        }
        if (!_matched_1) {
          if (Objects.equal(level,RCTimeLevel.level24h)) {
            _matched_1=true;
            BeanFactory _beanFactory = this.getBeanFactory();
            RCCTOProvider _bean = _beanFactory.<RCCTOProvider>getBean(RCCTOProvider.class);
            Party _party = _bean.getParty();
            final RCEmployee employee_2 = ((RCEmployee) _party);
            this.notifyEmployee(employee_2, "\u6280\u672F\u603B\u76D1");
          }
        }
        if (!_matched_1) {
        }
      }
    }
    if (!_matched) {
      if (Objects.equal(faultLevel,RCFaultLevel.level2)) {
        _matched=true;
        boolean _matched_2 = false;
        if (!_matched_2) {
          if (Objects.equal(level,RCTimeLevel.level4h)) {
            _matched_2=true;
            final RCEmployee employee_3 = this.seniorEngineer;
            this.notifyEmployee(employee_3, "\u8D44\u6DF1\u5DE5\u7A0B\u5E08");
          }
        }
        if (!_matched_2) {
          if (Objects.equal(level,RCTimeLevel.level24h)) {
            _matched_2=true;
            final RCEmployee employee_4 = this.techSupport;
            this.notifyEmployee(employee_4, "\u6280\u672F\u652F\u6301\u7ECF\u7406");
          }
        }
        if (!_matched_2) {
          if (Objects.equal(level,RCTimeLevel.level48h)) {
            _matched_2=true;
            BeanFactory _beanFactory_1 = this.getBeanFactory();
            RCCTOProvider _bean_1 = _beanFactory_1.<RCCTOProvider>getBean(RCCTOProvider.class);
            Party _party_1 = _bean_1.getParty();
            final RCEmployee employee_5 = ((RCEmployee) _party_1);
            this.notifyEmployee(employee_5, "\u6280\u672F\u603B\u76D1");
          }
        }
        if (!_matched_2) {
        }
      }
    }
    if (!_matched) {
      if (Objects.equal(faultLevel,RCFaultLevel.level3)) {
        _matched=true;
        boolean _matched_3 = false;
        if (!_matched_3) {
          if (Objects.equal(level,RCTimeLevel.level72h)) {
            _matched_3=true;
            final RCEmployee employee_6 = this.seniorEngineer;
            this.notifyEmployee(employee_6, "\u8D44\u6DF1\u5DE5\u7A0B\u5E08");
          }
        }
        if (!_matched_3) {
          if (Objects.equal(level,RCTimeLevel.level96h)) {
            _matched_3=true;
            final RCEmployee employee_7 = this.techSupport;
            this.notifyEmployee(employee_7, "\u6280\u672F\u652F\u6301\u7ECF\u7406");
          }
        }
        if (!_matched_3) {
        }
      }
    }
    if (!_matched) {
      if (Objects.equal(faultLevel,RCFaultLevel.level4)) {
        _matched=true;
        boolean _matched_4 = false;
        if (!_matched_4) {
          if (Objects.equal(level,RCTimeLevel.level96h)) {
            _matched_4=true;
            final RCEmployee employee_8 = this.seniorEngineer;
            this.notifyEmployee(employee_8, "\u8D44\u6DF1\u5DE5\u7A0B\u5E08");
          }
        }
        if (!_matched_4) {
        }
      }
    }
  }
  
  public void upgrade2Level(final RCTimeLevel level) {
    if(Flow==RCFaultReportFlow.reported||Flow==RCFaultReportFlow.processed){
    	_upgrade2Level(level);
    	getModelObjectLogService().createLog(this,"Flow","upgrade2Level");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCFaultReportEventsManager.class).fireUpgrade2Level(this,level);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Flow.name());
    }
  }
  
  private void _rMAPerformed(final String comment) {
    
    this.createEvent(comment, RCFaultReportEventType.RMAPerformed);
    this.status = RCFaultStatus.processed;
    Flow=RCFaultReportFlow.processed;
  }
  
  public void rMAPerformed(final String comment) {
    if(Flow==RCFaultReportFlow.waiting4rma){
    	_rMAPerformed(comment);
    	getModelObjectLogService().createLog(this,"Flow","RMAPerformed");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCFaultReportEventsManager.class).fireRMAPerformed(this,comment);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Flow.name());
    }
  }
  
  private void _startDeviceRMA(final RCFaultReportProduct device, final String comment) {
    
    this.createEvent(comment, RCFaultReportEventType.startDeviceRMA);
  }
  
  public void startDeviceRMA(final RCFaultReportProduct device, final String comment) {
    if(Flow==RCFaultReportFlow.waiting4rma){
    	_startDeviceRMA(device,comment);
    	getModelObjectLogService().createLog(this,"Flow","startDeviceRMA");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCFaultReportEventsManager.class).fireStartDeviceRMA(this,device,comment);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Flow.name());
    }
  }
  
  private void _finishDeviceRMA(final RCFaultReportProduct device, final String comment) {
    
    this.createEvent(comment, RCFaultReportEventType.finishDeviceRMA);
  }
  
  public void finishDeviceRMA(final RCFaultReportProduct device, final String comment) {
    if(Flow==RCFaultReportFlow.finished||Flow==RCFaultReportFlow.waiting4rma){
    	_finishDeviceRMA(device,comment);
    	getModelObjectLogService().createLog(this,"Flow","finishDeviceRMA");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCFaultReportEventsManager.class).fireFinishDeviceRMA(this,device,comment);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Flow.name());
    }
  }
  
  private void _resume(final String comment) {
    
    this.createEvent(comment, RCFaultReportEventType.resume);
    this.status = RCFaultStatus.processed;
    Flow=RCFaultReportFlow.processed;
  }
  
  public void resume(final String comment) {
    if(Flow==RCFaultReportFlow.pending){
    	_resume(comment);
    	getModelObjectLogService().createLog(this,"Flow","resume");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCFaultReportEventsManager.class).fireResume(this,comment);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Flow.name());
    }
  }
  
  private void _appendInfo(final String comment) {
    
    this.createEvent(comment, RCFaultReportEventType.appendInfo);
  }
  
  public void appendInfo(final String comment) {
    if(Flow==RCFaultReportFlow.reported||Flow==RCFaultReportFlow.processed||Flow==RCFaultReportFlow.waiting4rma||Flow==RCFaultReportFlow.processed||Flow==RCFaultReportFlow.pending||Flow==RCFaultReportFlow.finished){
    	_appendInfo(comment);
    	getModelObjectLogService().createLog(this,"Flow","appendInfo");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCFaultReportEventsManager.class).fireAppendInfo(this,comment);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Flow.name());
    }
  }
  
  private void _assign(final Procedure1<? super RCFaultWorkItem> preInit, final String comment, final Procedure1<? super RCFaultWorkItem> postProcess) {
    
    RCFaultWorkItem _createAndAddtoWorkItem = this.createAndAddtoWorkItem();
    final Procedure1<RCFaultWorkItem> _function = new Procedure1<RCFaultWorkItem>() {
        public void apply(final RCFaultWorkItem it) {
          preInit.apply(it);
          RCFaultReportImpl.this.createEvent(comment, RCFaultReportEventType.assign);
          it.start();
          postProcess.apply(it);
        }
      };
    ObjectExtensions.<RCFaultWorkItem>operator_doubleArrow(_createAndAddtoWorkItem, _function);
  }
  
  public void assign(final Procedure1<? super RCFaultWorkItem> preInit, final String comment, final Procedure1<? super RCFaultWorkItem> postProcess) {
    if(Flow==RCFaultReportFlow.waiting4rma||Flow==RCFaultReportFlow.processed||Flow==RCFaultReportFlow.pending){
    	_assign(preInit,comment,postProcess);
    	getModelObjectLogService().createLog(this,"Flow","assign");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCFaultReportEventsManager.class).fireAssign(this,preInit,comment,postProcess);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Flow.name());
    }
  }
  
  private void _engineerReport(final RCFaultWorkItem workItem, final String comment) {
    
    this.createEvent(comment, RCFaultReportEventType.engineerReport);
  }
  
  public void engineerReport(final RCFaultWorkItem workItem, final String comment) {
    if(Flow==RCFaultReportFlow.waiting4rma||Flow==RCFaultReportFlow.processed||Flow==RCFaultReportFlow.pending){
    	_engineerReport(workItem,comment);
    	getModelObjectLogService().createLog(this,"Flow","engineerReport");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCFaultReportEventsManager.class).fireEngineerReport(this,workItem,comment);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Flow.name());
    }
  }
  
  public Boolean isReported() {
    return com.shrct.businessprocess.customerservice.RCFaultReportFlow.reported==Flow;
  }
  
  public Boolean isProcessed() {
    return com.shrct.businessprocess.customerservice.RCFaultReportFlow.processed==Flow;
  }
  
  public Boolean isWaiting4rma() {
    return com.shrct.businessprocess.customerservice.RCFaultReportFlow.waiting4rma==Flow;
  }
  
  public Boolean isFinished() {
    return com.shrct.businessprocess.customerservice.RCFaultReportFlow.finished==Flow;
  }
  
  public Boolean isPending() {
    return com.shrct.businessprocess.customerservice.RCFaultReportFlow.pending==Flow;
  }
  
  private String sid;
  
  public String getSid() {
    return this.sid;
  }
  
  public RCFaultReport setSid(final String sid) {
    this.sid = sid;
    return this;			
    
  }
  
  private Date reportDate;
  
  public Date getReportDate() {
    return this.reportDate;
  }
  
  public RCFaultReport setReportDate(final Date reportDate) {
    this.reportDate = reportDate;
    return this;			
    
  }
  
  private Date reportTime;
  
  public Date getReportTime() {
    return this.reportTime;
  }
  
  public RCFaultReport setReportTime(final Date reportTime) {
    this.reportTime = reportTime;
    return this;			
    
  }
  
  private Date finishDate;
  
  public Date getFinishDate() {
    return this.finishDate;
  }
  
  public RCFaultReport setFinishDate(final Date finishDate) {
    this.finishDate = finishDate;
    return this;			
    
  }
  
  private Date finishTime;
  
  public Date getFinishTime() {
    return this.finishTime;
  }
  
  public RCFaultReport setFinishTime(final Date finishTime) {
    this.finishTime = finishTime;
    return this;			
    
  }
  
  private RCFaultLevel faultLevel;
  
  public RCFaultLevel getFaultLevel() {
    return this.faultLevel;
  }
  
  public RCFaultReport setFaultLevel(final RCFaultLevel faultLevel) {
    this.faultLevel = faultLevel;
    return this;			
    
  }
  
  private RCTimeLevel timeLevel;
  
  public RCTimeLevel getTimeLevel() {
    return this.timeLevel;
  }
  
  public RCFaultReport setTimeLevel(final RCTimeLevel timeLevel) {
    this.timeLevel = timeLevel;
    return this;			
    
  }
  
  private RCFaultStatus status = RCFaultStatus.reported;
  
  public RCFaultStatus getStatus() {
    return this.status;
  }
  
  public RCFaultReport setStatus(final RCFaultStatus status) {
    this.status = status;
    return this;			
    
  }
  
  private String comment;
  
  public String getComment() {
    return this.comment;
  }
  
  public RCFaultReport setComment(final String comment) {
    this.comment = comment;
    return this;			
    
  }
  
  @JoinColumn(name = "customer_id")
  @ManyToOne(targetEntity = RCEnterpriseImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCEnterprise customer;
  
  public RCEnterprise getCustomer() {
    return this.customer;
  }
  
  public RCFaultReport setCustomer(final RCEnterprise customer) {
    this.customer = customer;
    return this;			
    
  }
  
  private String reporter;
  
  public String getReporter() {
    return this.reporter;
  }
  
  public RCFaultReport setReporter(final String reporter) {
    this.reporter = reporter;
    return this;			
    
  }
  
  private String reporterPhone;
  
  public String getReporterPhone() {
    return this.reporterPhone;
  }
  
  public RCFaultReport setReporterPhone(final String reporterPhone) {
    this.reporterPhone = reporterPhone;
    return this;			
    
  }
  
  private String reporterMail;
  
  public String getReporterMail() {
    return this.reporterMail;
  }
  
  public RCFaultReport setReporterMail(final String reporterMail) {
    this.reporterMail = reporterMail;
    return this;			
    
  }
  
  private String reportLocation;
  
  public String getReportLocation() {
    return this.reportLocation;
  }
  
  public RCFaultReport setReportLocation(final String reportLocation) {
    this.reportLocation = reportLocation;
    return this;			
    
  }
  
  @JoinColumn(name = "seniorEngineer_id")
  @ManyToOne(targetEntity = RCEmployeeImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCEmployee seniorEngineer;
  
  public RCEmployee getSeniorEngineer() {
    return this.seniorEngineer;
  }
  
  public RCFaultReport setSeniorEngineer(final RCEmployee seniorEngineer) {
    this.seniorEngineer = seniorEngineer;
    return this;			
    
  }
  
  @JoinColumn(name = "techSupport_id")
  @ManyToOne(targetEntity = RCEmployeeImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCEmployee techSupport;
  
  public RCEmployee getTechSupport() {
    return this.techSupport;
  }
  
  public RCFaultReport setTechSupport(final RCEmployee techSupport) {
    this.techSupport = techSupport;
    return this;			
    
  }
  
  private Boolean marked = Boolean.valueOf(false);
  
  public Boolean getMarked() {
    return this.marked;
  }
  
  public RCFaultReport setMarked(final Boolean marked) {
    this.marked = marked;
    return this;			
    
  }
  
  @OneToMany(targetEntity = RCFaultReportEventImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "faultReport")
  private Collection<RCFaultReportEvent> events = new java.util.ArrayList<com.shrct.businessprocess.customerservice.RCFaultReportEvent>();;
  
  public Collection<RCFaultReportEvent> getEvents() {
    return this.events;
  }
  
  public RCFaultReportEvent createAndAddtoEvents() {
    getEvents().size();
    com.shrct.businessprocess.customerservice.RCFaultReportEvent rCFaultReportEvent = new com.shrct.businessprocess.customerservice.impl.RCFaultReportEventImpl(this);
    getObjectFactory().create(rCFaultReportEvent);
    getEvents().add(rCFaultReportEvent);
    return rCFaultReportEvent;
    
  }
  
  public RCFaultReportEvent createAndAddtoEvents(final Procedure1<RCFaultReportEvent> updater) {
    getEvents().size();
    com.shrct.businessprocess.customerservice.RCFaultReportEvent rCFaultReportEvent = new com.shrct.businessprocess.customerservice.impl.RCFaultReportEventImpl(this);
    getObjectFactory().create(rCFaultReportEvent);
    getEvents().add(rCFaultReportEvent);
    return rCFaultReportEvent;
    
  }
  
  public RCFaultReport removeAllEvents() {
    for(RCFaultReportEvent obj : this.events){
    	getObjectFactory().delete(obj);
    }
    this.events.clear();
    return this;	
    
  }
  
  public RCFaultReport removeFromEvents(final RCFaultReportEvent rCFaultReportEvent) {
    this.events.remove(rCFaultReportEvent);
    getObjectFactory().delete(rCFaultReportEvent);
    return this;
    
  }
  
  @OneToMany(targetEntity = RCFaultWorkItemImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "faultReport")
  private Collection<RCFaultWorkItem> workItem = new java.util.ArrayList<com.shrct.businessprocess.customerservice.RCFaultWorkItem>();;
  
  public Collection<RCFaultWorkItem> getWorkItem() {
    return this.workItem;
  }
  
  public RCFaultWorkItem createAndAddtoWorkItem() {
    getWorkItem().size();
    com.shrct.businessprocess.customerservice.RCFaultWorkItem rCFaultWorkItem = new com.shrct.businessprocess.customerservice.impl.RCFaultWorkItemImpl(this);
    getObjectFactory().create(rCFaultWorkItem);
    getWorkItem().add(rCFaultWorkItem);
    return rCFaultWorkItem;
    
  }
  
  public RCFaultWorkItem createAndAddtoWorkItem(final Procedure1<RCFaultWorkItem> updater) {
    getWorkItem().size();
    com.shrct.businessprocess.customerservice.RCFaultWorkItem rCFaultWorkItem = new com.shrct.businessprocess.customerservice.impl.RCFaultWorkItemImpl(this);
    getObjectFactory().create(rCFaultWorkItem);
    getWorkItem().add(rCFaultWorkItem);
    return rCFaultWorkItem;
    
  }
  
  public RCFaultReport removeAllWorkItem() {
    for(RCFaultWorkItem obj : this.workItem){
    	getObjectFactory().delete(obj);
    }
    this.workItem.clear();
    return this;	
    
  }
  
  public RCFaultReport removeFromWorkItem(final RCFaultWorkItem rCFaultWorkItem) {
    this.workItem.remove(rCFaultWorkItem);
    getObjectFactory().delete(rCFaultWorkItem);
    return this;
    
  }
  
  @OneToMany(targetEntity = RCFaultReportProductImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "faultReport")
  private Collection<RCFaultReportProduct> products = new java.util.ArrayList<com.shrct.businessprocess.customerservice.RCFaultReportProduct>();;
  
  public Collection<RCFaultReportProduct> getProducts() {
    return this.products;
  }
  
  public RCFaultReportProduct createAndAddtoProducts() {
    getProducts().size();
    com.shrct.businessprocess.customerservice.RCFaultReportProduct rCFaultReportProduct = new com.shrct.businessprocess.customerservice.impl.RCFaultReportProductImpl(this);
    getObjectFactory().create(rCFaultReportProduct);
    getProducts().add(rCFaultReportProduct);
    return rCFaultReportProduct;
    
  }
  
  public RCFaultReportProduct createAndAddtoProducts(final Procedure1<RCFaultReportProduct> updater) {
    getProducts().size();
    com.shrct.businessprocess.customerservice.RCFaultReportProduct rCFaultReportProduct = new com.shrct.businessprocess.customerservice.impl.RCFaultReportProductImpl(this);
    getObjectFactory().create(rCFaultReportProduct);
    getProducts().add(rCFaultReportProduct);
    return rCFaultReportProduct;
    
  }
  
  public RCFaultReport removeAllProducts() {
    for(RCFaultReportProduct obj : this.products){
    	getObjectFactory().delete(obj);
    }
    this.products.clear();
    return this;	
    
  }
  
  public RCFaultReport removeFromProducts(final RCFaultReportProduct rCFaultReportProduct) {
    this.products.remove(rCFaultReportProduct);
    getObjectFactory().delete(rCFaultReportProduct);
    return this;
    
  }
  
  @ManyToMany(targetEntity = RCEmployeeImpl.class)
  @JoinTable(name = "m2m_rcfaultreport_relatedemployees", joinColumns = @JoinColumn(name = "rcfaultreport_id") , inverseJoinColumns = @JoinColumn(name = "rCEmployee_inv_id") )
  private Collection<RCEmployee> relatedEmployees = new java.util.ArrayList<com.shrct.businessprocess.organization.RCEmployee>();;
  
  public Collection<RCEmployee> getRelatedEmployees() {
    return this.relatedEmployees;
  }
  
  public RCFaultReport setRelatedEmployees(final Iterable<RCEmployee> relatedEmployees) {
    removeAllRelatedEmployees();
    for(RCEmployee ca : relatedEmployees){
    	addtoRelatedEmployees(ca);
    }
    return this;		
    
  }
  
  public RCFaultReport addtoRelatedEmployees(final RCEmployee rCEmployee) {
    this.relatedEmployees.add(rCEmployee);
    return this;
    
  }
  
  public RCFaultReport removeAllRelatedEmployees() {
    this.relatedEmployees.clear();
    return this;	
    
  }
  
  public RCFaultReport removeFromRelatedEmployees(final RCEmployee rCEmployee) {
    this.relatedEmployees.remove(rCEmployee);
    return this;
    
  }
  
  @ManyToMany(targetEntity = RCServiceRecordImpl.class)
  @JoinTable(name = "m2m_rcfaultreport_servicerecords", joinColumns = @JoinColumn(name = "rcfaultreport_id") , inverseJoinColumns = @JoinColumn(name = "rCServiceRecord_inv_id") )
  private Collection<RCServiceRecord> serviceRecords = new java.util.ArrayList<com.shrct.businessprocess.customerservice.RCServiceRecord>();;
  
  public Collection<RCServiceRecord> getServiceRecords() {
    return this.serviceRecords;
  }
  
  public RCFaultReport setServiceRecords(final Iterable<RCServiceRecord> serviceRecords) {
    removeAllServiceRecords();
    for(RCServiceRecord ca : serviceRecords){
    	addtoServiceRecords(ca);
    }
    return this;		
    
  }
  
  public RCFaultReport addtoServiceRecords(final RCServiceRecord rCServiceRecord) {
    this.serviceRecords.add(rCServiceRecord);
    return this;
    
  }
  
  public RCFaultReport removeAllServiceRecords() {
    this.serviceRecords.clear();
    return this;	
    
  }
  
  public RCFaultReport removeFromServiceRecords(final RCServiceRecord rCServiceRecord) {
    this.serviceRecords.remove(rCServiceRecord);
    return this;
    
  }
  
  private String customerComment;
  
  public String getCustomerComment() {
    return this.customerComment;
  }
  
  public RCFaultReport setCustomerComment(final String customerComment) {
    this.customerComment = customerComment;
    return this;			
    
  }
  
  private Integer customerEval;
  
  public Integer getCustomerEval() {
    return this.customerEval;
  }
  
  public RCFaultReport setCustomerEval(final Integer customerEval) {
    this.customerEval = customerEval;
    return this;			
    
  }
  
  public Boolean allWorkItemFinished() {
    final Function1<RCFaultWorkItem,Boolean> _function = new Function1<RCFaultWorkItem,Boolean>() {
        public Boolean apply(final RCFaultWorkItem it) {
          Boolean _isFinished = it.isFinished();
          return _isFinished;
        }
      };
    boolean _forall = IterableExtensions.<RCFaultWorkItem>forall(this.workItem, _function);
    return Boolean.valueOf(_forall);
  }
  
  public Collection<RCFaultReportRMAInfo> getRMAs() {
    IGenericQuery<RCFaultReportRMAInfo> query=getObjectFactory().createGenericQuery(RCFaultReportRMAInfo.class,"select e from com.shrct.businessprocess.customerservice.impl.RCFaultReportRMAInfoImpl as e   where ((e.product.faultReport) = (:this)) and  e.active = 1      ").setParameter("this",this);
    Collection<RCFaultReportRMAInfo> _list = query.list();
    return _list;
  }
  
  public void mark() {
    this.marked = Boolean.valueOf(true);
  }
  
  public void unmark() {
    this.marked = Boolean.valueOf(false);
  }
  
  public RCFaultReportProduct registerFaultProduct(final RCIdentifiablePhysicalProductEntry product) {RCFaultReportProduct rCFaultReportProduct=RCFaultReportProductImpl.create(this,getObjectFactory());
    final Procedure1<RCFaultReportProduct> _function = new Procedure1<RCFaultReportProduct>() {
        public void apply(final RCFaultReportProduct it) {
          it.setProduct(product);
        }
      };
    RCFaultReportProduct _doubleArrow = ObjectExtensions.<RCFaultReportProduct>operator_doubleArrow(rCFaultReportProduct, _function);
    return _doubleArrow;
  }
  
  public void removeFaultProduct(final RCFaultReportProduct faultProduct) {getObjectFactory().delete(faultProduct);
    
  }
  
  public void updateCurrentLevel() {
    Date _now = DateUtil.now();
    long _time = _now.getTime();
    long _time_1 = this.reportTime.getTime();
    long _minus = (_time - _time_1);
    float _multiply = (60f * 60f);
    float _multiply_1 = (_multiply * 1000f);
    final float diff = (_minus / _multiply_1);
    RCTimeLevel _xifexpression = null;
    boolean _greaterEqualsThan = (diff >= 96);
    if (_greaterEqualsThan) {
      _xifexpression = RCTimeLevel.level96h;
    } else {
      RCTimeLevel _xifexpression_1 = null;
      boolean _greaterEqualsThan_1 = (diff >= 72);
      if (_greaterEqualsThan_1) {
        _xifexpression_1 = RCTimeLevel.level72h;
      } else {
        RCTimeLevel _xifexpression_2 = null;
        boolean _greaterEqualsThan_2 = (diff >= 48);
        if (_greaterEqualsThan_2) {
          _xifexpression_2 = RCTimeLevel.level48h;
        } else {
          RCTimeLevel _xifexpression_3 = null;
          boolean _greaterEqualsThan_3 = (diff >= 24);
          if (_greaterEqualsThan_3) {
            _xifexpression_3 = RCTimeLevel.level24h;
          } else {
            RCTimeLevel _xifexpression_4 = null;
            boolean _greaterEqualsThan_4 = (diff >= 4);
            if (_greaterEqualsThan_4) {
              _xifexpression_4 = RCTimeLevel.level4h;
            } else {
              RCTimeLevel _xifexpression_5 = null;
              boolean _greaterEqualsThan_5 = (diff >= 1);
              if (_greaterEqualsThan_5) {
                _xifexpression_5 = RCTimeLevel.level1h;
              }
              _xifexpression_4 = _xifexpression_5;
            }
            _xifexpression_3 = _xifexpression_4;
          }
          _xifexpression_2 = _xifexpression_3;
        }
        _xifexpression_1 = _xifexpression_2;
      }
      _xifexpression = _xifexpression_1;
    }
    final RCTimeLevel curTimeLevel = _xifexpression;
    boolean _notEquals = (!Objects.equal(curTimeLevel, this.timeLevel));
    if (_notEquals) {
      String _name = this.timeLevel==null?(String)null:this.timeLevel.name();
      String _name_1 = curTimeLevel==null?(String)null:curTimeLevel.name();
      String _format = String.format("CASE %s upgrade from %s to %s", this.sid, _name, _name_1);
      InputOutput.<String>println(_format);
      this.upgrade2Level(curTimeLevel);
      this.timeLevel = curTimeLevel;
    }
  }
  
  public RCFaultReportEvent createEvent(final String comment, final RCFaultReportEventType type) {
    Date _now = DateUtil.now();
    RCFaultReportEvent _createEvent = this.createEvent(comment, type, _now);
    return _createEvent;
  }
  
  public void doAddtoServiceRecords(final RCServiceRecord serviceRecord) {
    boolean _contains = this.serviceRecords.contains(serviceRecord);
    boolean _not = (!_contains);
    if (_not) {
      this.addtoServiceRecords(serviceRecord);
    }
  }
  
  public RCFaultReportEvent createEvent(final String comment, final RCFaultReportEventType type, final Date time) {
    RCFaultReportEvent _xblockexpression = null;
    {
      BeanFactory _beanFactory = this.getBeanFactory();
      final ISystemUserService systemUserService = _beanFactory.<ISystemUserService>getBean(ISystemUserService.class);RCFaultReportEvent rCFaultReportEvent=RCFaultReportEventImpl.create(this,getObjectFactory());
      final Procedure1<RCFaultReportEvent> _function = new Procedure1<RCFaultReportEvent>() {
          public void apply(final RCFaultReportEvent it) {
            it.setDateTime(time);
            it.setComment(comment);
            it.setType(type);
            RCFaultReportImpl.this.events.add(it);
            Party _currentUserAsParty = systemUserService.getCurrentUserAsParty();
            it.setOperator(((RCEmployee) _currentUserAsParty));
          }
        };
      RCFaultReportEvent _doubleArrow = ObjectExtensions.<RCFaultReportEvent>operator_doubleArrow(rCFaultReportEvent, _function);
      _xblockexpression = (_doubleArrow);
    }
    return _xblockexpression;
  }
  
  public RCFaultReportEvent createSystemEvent(final String comment, final RCFaultReportEventType type) {RCFaultReportEvent rCFaultReportEvent=RCFaultReportEventImpl.create(this,getObjectFactory());
    final Procedure1<RCFaultReportEvent> _function = new Procedure1<RCFaultReportEvent>() {
        public void apply(final RCFaultReportEvent it) {
          Date _now = DateUtil.now();
          it.setDateTime(_now);
          it.setComment(comment);
          it.setType(type);
          RCFaultReportImpl.this.events.add(it);
          it.setOperator(null);
        }
      };
    RCFaultReportEvent _doubleArrow = ObjectExtensions.<RCFaultReportEvent>operator_doubleArrow(rCFaultReportEvent, _function);
    return _doubleArrow;
  }
  
  public void deleteEvent(final RCFaultReportEvent event) {
    this.removeFromEvents(event);
  }
  
  public void notifyEmployee(final RCEmployee employee, final String role) {
    this.doNotifyEmployee(employee, role);
    this.doNotifyRelatedEmployees();
  }
  
  public void doNotifyRelatedEmployees() {
    final Procedure1<RCEmployee> _function = new Procedure1<RCEmployee>() {
        public void apply(final RCEmployee it) {
          RCFaultReportImpl.this.doNotifyEmployee(it, "\u76F8\u5173\u4EBA\u5458");
        }
      };
    IterableExtensions.<RCEmployee>forEach(this.relatedEmployees, _function);
  }
  
  public void doNotifyEmployee(final RCEmployee employee, final String role) {
    try {
      BeanFactory _beanFactory = this.getBeanFactory();
      final MailSender mailSender = _beanFactory.<MailSender>getBean(MailSender.class);
      SimpleMailMessage _simpleMailMessage = new SimpleMailMessage();
      final SimpleMailMessage message = _simpleMailMessage;
      String _plus = ("CASE \u5347\u7EA7\u901A\u77E5,CASE\u53F7:" + this.sid);
      message.setSubject(_plus);
      String _email = employee==null?(String)null:employee.getEmail();
      message.setTo(_email);
      message.setCc("bjjin@shrct.com");
      message.setFrom("caseadmin@shrct.com");
      String _email_1 = employee==null?(String)null:employee.getEmail();
      String _plus_1 = ("\u5E94\u901A\u77E5\u4EBA\uFF1A" + _email_1);
      String _plus_2 = (_plus_1 + "\n");
      String _plus_3 = (_plus_2 + 
        "\u62A5\u4FEE\u65F6\u95F4:");
      String _string = this.reportTime.toString();
      String _plus_4 = (_plus_3 + _string);
      String _plus_5 = (_plus_4 + "\n");
      String _plus_6 = (_plus_5 + 
        "\u62A5\u4FEE\u5BA2\u6237:");
      String _name = this.customer==null?(String)null:this.customer.getName();
      String _plus_7 = (_plus_6 + _name);
      String _plus_8 = (_plus_7 + "\n");
      String _plus_9 = (_plus_8 + 
        "\u901A\u77E5\u53D1\u51FA\u65F6\u95F4:");
      Date _now = DateUtil.now();
      String _string_1 = _now.toString();
      String _plus_10 = (_plus_9 + _string_1);
      String _plus_11 = (_plus_10 + "\n");
      String _plus_12 = (_plus_11 + 
        "CASE\u7EA7\u522B:");
      String _string_2 = this.faultLevel.toString();
      String _plus_13 = (_plus_12 + _string_2);
      String _plus_14 = (_plus_13 + "\n");
      String _plus_15 = (_plus_14 + 
        "\u62A5\u4FEE\u5185\u5BB9:");
      String _nullsafe = StringExtensions.nullsafe(this.comment);
      final String msgBody = (_plus_15 + _nullsafe);
      String _nullsafe_1 = StringExtensions.nullsafe(this.comment);
      String _plus_16 = ("\u62A5\u4FEE\u5185\u5BB9:" + _nullsafe_1);
      InputOutput.<String>println(_plus_16);
      InputOutput.<String>println(msgBody);
      message.setText(msgBody);
      mailSender.send(message);
      String _name_1 = employee==null?(String)null:employee.getName();
      String _email_2 = employee==null?(String)null:employee.getEmail();
      String _format = String.format("CASE\u5347\u7EA7\uFF0C\u901A\u77E5%s%s(%s)", role, _name_1, _email_2);
      this.createSystemEvent(_format, RCFaultReportEventType.caseUpgrade);
    } catch (final Throwable _t) {
      if (_t instanceof Exception) {
        final Exception e = (Exception)_t;
        String _name_2 = employee==null?(String)null:employee.getName();
        String _email_3 = employee==null?(String)null:employee.getEmail();
        String _message = e.getMessage();
        String _format_1 = String.format("CASE\u5347\u7EA7\uFF0C\u901A\u77E5%s%s(%s), \u90AE\u4EF6\u901A\u77E5\u5931\u8D25(%s)", role, _name_2, _email_3, _message);
        this.createSystemEvent(_format_1, RCFaultReportEventType.caseUpgrade);
        e.printStackTrace();
      } else {
        throw Exceptions.sneakyThrow(_t);
      }
    }
  }
  
  public static RCFaultReport create(final IObjectFactory objectFactory) {
    com.shrct.businessprocess.customerservice.RCFaultReport rCFaultReport = new com.shrct.businessprocess.customerservice.impl.RCFaultReportImpl(
    );
    objectFactory.create(rCFaultReport);
    return rCFaultReport;			
    
  }
  
  public static RCFaultReport createRCFaultReportImpl(final IObjectFactory objectFactory, final Procedure1<RCFaultReport> init) {
    com.shrct.businessprocess.customerservice.RCFaultReport rCFaultReport = new com.shrct.businessprocess.customerservice.impl.RCFaultReportImpl(
    );
    objectFactory.create(rCFaultReport);
    init.apply(rCFaultReport);
    
    return rCFaultReport;			
    
  }
  
  public RCFaultReportProxy toProxy() {
    com.shrct.businessprocess.customerservice.proxy.RCFaultReportProxy proxy = new com.shrct.businessprocess.customerservice.proxy.RCFaultReportProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    proxy.setFlow(this.getFlow().name());
    return proxy;
    
  }
}
